using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AutoMapper;
using DHM.IRepository;
using DHM.IService;
using DHM.Repository;
using DHM.Service;
using DHM.WXMiniProgram.Utility.AutoMapper;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using SqlSugar;
using SqlSugar.IOC;

namespace DHM.WXMiniProgram {
    public class Startup {
        public Startup (IConfiguration configuration) {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices (IServiceCollection services) {

            services.AddControllers ();
            services.AddSwaggerGen (c => {
                c.SwaggerDoc ("v1", new OpenApiInfo { Title = "DHM.WXMiniProgram", Version = "v1" });

                c.AddSecurityDefinition ("Bearer", new OpenApiSecurityScheme {
                    In = ParameterLocation.Header,
                        Type = SecuritySchemeType.ApiKey,
                        Description = "ֱ请输入Bearer {token} 注意Bearer后面是一个空格",
                        Name = "Authorization",
                        BearerFormat = "JWT",
                        Scheme = "Bearer"
                });
                c.AddSecurityRequirement (new OpenApiSecurityRequirement {
                    {
                        new OpenApiSecurityScheme {
                            Reference = new OpenApiReference {
                                Type = ReferenceType.SecurityScheme,
                                    Id = "Bearer"
                            }
                        },
                        new string[] { }
                    }
                });
            });

            #region SqlSugarIOC

            services.AddSqlSugar (new IocConfig {
                ConnectionString = Configuration["SQLConnect"],
                    DbType = IocDbType.MySql,
                    IsAutoCloseConnection = true
            });

            #endregion

            #region CustomIOD

            services.AddMemoryCache ();

            services.AddCustomIOC ();

            services.AddCustomJWT (Configuration);

            services.AddAutoMapper (typeof (CustomAutoMapperProfile));

            #endregion
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure (IApplicationBuilder app, IWebHostEnvironment env, ILogger<Startup> logger) {
            if (env.IsDevelopment ()) {
                app.UseDeveloperExceptionPage ();
                app.UseSwagger ();
                app.UseSwaggerUI (c => c.SwaggerEndpoint ("/swagger/v1/swagger.json", "DHM.WXMiniProgram v1"));
            }

            // app.AddCustomMime(Configuration);

            app.UseRouting ();

            // app.UseHttpsRedirection();

            //  app.UseFileServer(enableDirectoryBrowsing:true);

            app.UseStaticFiles (
                new StaticFileOptions {
                    FileProvider = new PhysicalFileProvider (Path.Combine (env.WebRootPath)),
                    ContentTypeProvider = AddCustomMime (Configuration)
                }
            );
            logger.LogInformation(app.ToString());
            //用户授权
            app.UseAuthentication ();
            //用户鉴权
            app.UseAuthorization ();

            app.UseEndpoints (endpoints => { endpoints.MapControllers (); });
        }
        /// <summary>
        /// 添加自定义MIME类型
        /// </summary>
        /// <param name="configuration"></param>
        /// <returns></returns>
        public IContentTypeProvider AddCustomMime (IConfiguration configuration) {

            var provider = new FileExtensionContentTypeProvider ();
            var mimes = configuration.GetSection ("CustomMIME").GetChildren ();
            foreach (var mime in mimes) {
                provider.Mappings[mime.Key] = mime.Value;
            }
            return provider;
        }
    }
}
/// <summary>
/// 自定义扩展方法
/// </summary>
public static class IOCExtend {
    public static IServiceCollection AddCustomIOC (this IServiceCollection services) {
        services.AddScoped<IUserCommentRepositiry, UserCommentRepository> ();
        services.AddScoped<IUserCommentService, UserCommentService> ();

        services.AddScoped<IUseLikesRepository, UserLikesRepository> ();
        services.AddScoped<IUserLikesService, UserLikeService> ();

        services.AddScoped<IUserViewsRepository, UserViewsRepository> ();
        services.AddScoped<IUserViewsService, UserViewsService> ();

        return services;
    }

    public static IServiceCollection AddCustomJWT (this IServiceCollection services, IConfiguration configuration) {
        services.AddAuthentication (JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer (options => {
                options.TokenValidationParameters = new TokenValidationParameters {
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = new SymmetricSecurityKey (Encoding.UTF8.GetBytes (configuration["JWT_Secretkey"])),
                ValidateIssuer = false,
                ValidateAudience = false,
                ValidateLifetime = true,
                ClockSkew = TimeSpan.FromMinutes (5)
                };
            });
        return services;
    }

}